package com.smartsystem.modules.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.smartsystem.common.exception.BusinessException;
import com.smartsystem.common.utils.PasswordUtils;
import com.smartsystem.modules.system.dto.SysUserDTO;
import com.smartsystem.modules.system.dto.SysUserQueryDTO;
import com.smartsystem.modules.system.entity.SysUser;
import com.smartsystem.modules.system.entity.SysUserRole;
import com.smartsystem.modules.system.mapper.SysUserMapper;
import com.smartsystem.modules.system.mapper.SysUserRoleMapper;
import com.smartsystem.modules.system.service.SysUserService;
import com.smartsystem.modules.system.vo.SysUserVO;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 用户表Service实现类
 */
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {
    
    @Resource
    private SysUserMapper sysUserMapper;
    
    @Resource
    private SysUserRoleMapper sysUserRoleMapper;
    
    @Override
    public SysUser findByUsername(String username) {
        return sysUserMapper.findByUsername(username);
    }
    
    @Override
    public List<Long> getUserRoles(Long userId) {
        return sysUserRoleMapper.findRoleIdsByUserId(userId);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateUserRoles(Long userId, List<Long> roleIds) {
        // 删除原有角色关联
        LambdaQueryWrapper<SysUserRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysUserRole::getUserId, userId);
        sysUserRoleMapper.delete(queryWrapper);
        
        // 添加新的角色关联
        if (roleIds != null && !roleIds.isEmpty()) {
            List<SysUserRole> userRoles = roleIds.stream().map(roleId -> {
                SysUserRole userRole = new SysUserRole();
                userRole.setUserId(userId);
                userRole.setRoleId(roleId);
                return userRole;
            }).collect(Collectors.toList());
            // Use standard MyBatis-Plus batch insert method
            userRoles.forEach(sysUserRoleMapper::insert);
        }
    }
    
    @Override
    public SysUser validateUser(String username, String password) {
        SysUser user = findByUsername(username);
        if (user == null) {
            throw new BusinessException(401, "用户名不存在");
        }
        
        // 实际应用中应该使用加密密码验证
        if (!PasswordUtils.matches(password, user.getPassword())) {
            throw new BusinessException(401, "密码错误");
        }
        
        // 检查用户状态
        if (user.getStatus() == 0) {
            throw new BusinessException(403, "用户已禁用");
        }
        
        return user;
    }

    @Override
    public IPage<SysUserVO> getUserPage(SysUserQueryDTO queryDTO) {
        Page<SysUser> page = new Page<>(queryDTO.getCurrent(), queryDTO.getSize());
        
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.hasText(queryDTO.getUsername()), SysUser::getUsername, queryDTO.getUsername())
                   .like(StringUtils.hasText(queryDTO.getRealName()), SysUser::getRealName, queryDTO.getRealName())
                   .like(StringUtils.hasText(queryDTO.getPhone()), SysUser::getPhone, queryDTO.getPhone())
                   .like(StringUtils.hasText(queryDTO.getEmail()), SysUser::getEmail, queryDTO.getEmail())
                   .eq(queryDTO.getStatus() != null, SysUser::getStatus, queryDTO.getStatus())
                   .like(StringUtils.hasText(queryDTO.getDepartment()), SysUser::getDepartment, queryDTO.getDepartment())
                   .orderByDesc(SysUser::getCreateTime);
        
        IPage<SysUser> userPage = this.page(page, queryWrapper);
        
        // 转换为VO
        IPage<SysUserVO> voPage = new Page<>(userPage.getCurrent(), userPage.getSize(), userPage.getTotal());
        List<SysUserVO> voList = userPage.getRecords().stream().map(this::convertToVO).collect(Collectors.toList());
        voPage.setRecords(voList);
        
        return voPage;
    }

    @Override
    public SysUserVO getUserById(Long id) {
        SysUser user = this.getById(id);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }
        return convertToVO(user);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createUser(SysUserDTO userDTO) {
        SysUser user = new SysUser();
        BeanUtils.copyProperties(userDTO, user);
        
        // 密码加密
        if (StringUtils.hasText(userDTO.getPassword())) {
            user.setPassword(PasswordUtils.encodePassword(userDTO.getPassword()));
        }
        
        // 保存用户
        this.save(user);
        
        // 保存用户角色关联
        if (userDTO.getRoleIds() != null && !userDTO.getRoleIds().isEmpty()) {
            updateUserRoles(user.getId(), userDTO.getRoleIds());
        }
        
        return user.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateUser(SysUserDTO userDTO) {
        SysUser user = this.getById(userDTO.getId());
        if (user == null) {
            throw new BusinessException("用户不存在");
        }
        
        // 复制属性（排除密码）
        BeanUtils.copyProperties(userDTO, user, "password");
        
        // 如果提供了新密码，则更新密码
        if (StringUtils.hasText(userDTO.getPassword())) {
            user.setPassword(PasswordUtils.encodePassword(userDTO.getPassword()));
        }
        
        // 更新用户
        boolean result = this.updateById(user);
        
        // 更新用户角色关联
        if (userDTO.getRoleIds() != null) {
            updateUserRoles(user.getId(), userDTO.getRoleIds());
        }
        
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteUser(Long id) {
        // 检查用户是否存在
        SysUser user = this.getById(id);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }
        
        // 删除用户角色关联
        LambdaQueryWrapper<SysUserRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysUserRole::getUserId, id);
        sysUserRoleMapper.delete(queryWrapper);
        
        // 删除用户
        return this.removeById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteUsers(List<Long> ids) {
        if (ids == null || ids.isEmpty()) {
            return false;
        }
        
        // 删除用户角色关联
        LambdaQueryWrapper<SysUserRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(SysUserRole::getUserId, ids);
        sysUserRoleMapper.delete(queryWrapper);
        
        // 批量删除用户
        return this.removeByIds(ids);
    }

    @Override
    public Boolean resetPassword(Long id, String newPassword) {
        SysUser user = this.getById(id);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }
        
        user.setPassword(PasswordUtils.encodePassword(newPassword));
        return this.updateById(user);
    }

    @Override
    public Boolean updateStatus(Long id, Integer status) {
        SysUser user = this.getById(id);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }
        
        user.setStatus(status);
        return this.updateById(user);
    }

    @Override
    public Boolean checkUsernameExists(String username, Long excludeId) {
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysUser::getUsername, username);
        if (excludeId != null) {
            queryWrapper.ne(SysUser::getId, excludeId);
        }
        return this.count(queryWrapper) > 0;
    }

    @Override
    public Boolean checkPhoneExists(String phone, Long excludeId) {
        if (!StringUtils.hasText(phone)) {
            return false;
        }
        
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysUser::getPhone, phone);
        if (excludeId != null) {
            queryWrapper.ne(SysUser::getId, excludeId);
        }
        return this.count(queryWrapper) > 0;
    }

    @Override
    public Boolean checkEmailExists(String email, Long excludeId) {
        if (!StringUtils.hasText(email)) {
            return false;
        }
        
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysUser::getEmail, email);
        if (excludeId != null) {
            queryWrapper.ne(SysUser::getId, excludeId);
        }
        return this.count(queryWrapper) > 0;
    }

    /**
     * 转换为VO对象
     */
    private SysUserVO convertToVO(SysUser user) {
        SysUserVO vo = new SysUserVO();
        BeanUtils.copyProperties(user, vo);
        
        // 设置性别描述
        if (user.getGender() != null) {
            vo.setGenderName(user.getGender() == 1 ? "男" : "女");
        }
        
        // 设置状态描述
        vo.setStatusName(user.getStatus() == 1 ? "启用" : "禁用");
        
        // TODO: 获取用户角色信息
        // 这里暂时设置为空列表，后续完善角色管理后再实现
        vo.setRoles(new ArrayList<>());
        
        return vo;
    }
}